/*
 * Copyright (c) Huawei Device Co., Ltd. 2023. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "se_service.h"

#include "channel.h"
#include "session.h"
#include "reader.h"

#include <gtest/gtest.h>
#include <memory>

#include "ipc_object_stub.h"
#include "loghelper.h"
#include "service_manager.h"
#include "secure_element_agent.h"

namespace OHOS {
namespace SE {
namespace TEST {
using namespace testing::ext;
using namespace OHOS::SE::OMAPI;
const std::string VERSION = "3.3";
static bool isSeSupported = false;

class SeServiceTest : public testing::Test {
public:
    static void SetUpTestCase() {};
    static void TearDownTestCase() {};
    void SetUp();
    void TearDown();
public:
    std::shared_ptr<SEService> seService_;
};

void SeServiceTest::SetUp()
{
    InfoLog("SeServiceTest::SetUp begin!");
    seService_ = std::make_shared<SEService>();
    bool initStatus = false;
    seService_->InitSEService(initStatus, nullptr);
    sleep(1);
    EXPECT_TRUE(initStatus);

    vector<std::shared_ptr<Reader>> readerLists;
    seService_->GetReaders(readerLists);
    isSeSupported = readerLists.empty();
    if (isSeSupported) {
        ErrorLog("se not support!");
        return;
    }
    InfoLog("SeServiceTest::SetUp done!");
}

void SeServiceTest::TearDown()
{
    InfoLog("SeServiceTest::TearDown begin!");
    if (isSeSupported) {
        ErrorLog("se not support!");
        return;
    }
    seService_->Shutdown();

    bool isConnected = false;
    int statusCode = seService_->IsConnected(isConnected);
    EXPECT_TRUE(statusCode == ErrorCode::SE_SUCCESS);
    EXPECT_FALSE(isConnected);
    seService_ = nullptr;
    InfoLog("SeServiceTest::TearDown done!");
}

/**
 * @tc.name: IsConnected_Test001
 * @tc.desc: Test SeService GetReaders.
 * @tc.type: FUNC
 */
HWTEST_F(SeServiceTest, IsConnected_Test001, TestSize.Level1)
{
    if (isSeSupported) {
        ErrorLog("se not support!");
        return;
    }
    if (seService_ != nullptr) {
        bool isConnected = false;
        int statusCode = seService_->IsConnected(isConnected);
        EXPECT_TRUE(statusCode == ErrorCode::SE_SUCCESS);
        EXPECT_TRUE(isConnected);
    }
}

/**
 * @tc.name: GetReaders_Test001
 * @tc.desc: Test SeService GetReaders.
 * @tc.type: FUNC
 */
HWTEST_F(SeServiceTest, GetReaders_Test001, TestSize.Level1)
{
    if (isSeSupported) {
        ErrorLog("se not support!");
        return;
    }
    if (seService_ != nullptr) {
        std::vector<std::shared_ptr<Reader>> readers;
        int statusCode = seService_->GetReaders(readers);
        EXPECT_TRUE(statusCode == ErrorCode::SE_SUCCESS);
        EXPECT_FALSE(readers.empty());
    }
}

/**
 * @tc.name: GetVersion
 * @tc.desc: Test SeService GetVersion.
 * @tc.type: FUNC
 */
HWTEST_F(SeServiceTest, GetVersion001, TestSize.Level1)
{
    if (isSeSupported) {
        ErrorLog("se not support!");
        return;
    }
    if (seService_ != nullptr) {
        std::string version;
        int statusCode = seService_->GetVersion(version);
        EXPECT_TRUE(statusCode == ErrorCode::SE_SUCCESS);
        EXPECT_STREQ(version.c_str(), VERSION.c_str());
    }
}

/**
 * @tc.name: Shutdown
 * @tc.desc: Test SeService Shutdown.
 * @tc.type: FUNC
 */
HWTEST_F(SeServiceTest, Shutdown001, TestSize.Level1)
{
    if (isSeSupported) {
        ErrorLog("se not support!");
        return;
    }
    if (seService_ != nullptr) {
        seService_->Shutdown();

        bool isConnected = false;
        int statusCode = seService_->IsConnected(isConnected);
        EXPECT_TRUE(statusCode == ErrorCode::SE_SUCCESS);
        EXPECT_FALSE(isConnected);
    }
}

/**
 * @tc.name: CloseChannel
 * @tc.desc: Test SeService CloseChannel.
 * @tc.type: FUNC
 */
HWTEST_F(SeServiceTest, CloseChannel001, TestSize.Level1)
{
    if (isSeSupported) {
        ErrorLog("se not support!");
        return;
    }
    if (seService_ != nullptr) {
        seService_->Shutdown();

        bool isConnected = false;
        int statusCode = seService_->IsConnected(isConnected);
        EXPECT_TRUE(statusCode == ErrorCode::SE_SUCCESS);
        EXPECT_FALSE(isConnected);
    }
}

/**
 * @tc.name: CloseChannel
 * @tc.desc: Test SeService CloseChannel.
 * @tc.type: FUNC
 */
HWTEST_F(SeServiceTest, CloseChannel002, TestSize.Level1)
{
    std::shared_ptr<SecureElementAgent> seService;
    seService = std::make_shared<SecureElementAgent>("");
    std::string callingUniqueTag = "";
    if (seService != nullptr) {
        seService->CloseChannel(0, true, callingUniqueTag);
    }
    EXPECT_TRUE(seService != nullptr);
}

/**
 * @tc.name: OnRemoteDied
 * @tc.desc: Test SeService OnRemoteDied.
 * @tc.type: FUNC
 */
HWTEST_F(SeServiceTest, OnRemoteDied001, TestSize.Level1)
{
    std::shared_ptr<SEService> seService = std::make_shared<SEService>();
    seService->OnRemoteDied(nullptr);
    EXPECT_TRUE(seService != nullptr);
}

/**
 * @tc.name: GetReaders
 * @tc.desc: Test SeService GetReaders.
 * @tc.type: FUNC
 */
HWTEST_F(SeServiceTest, GetReaders003, TestSize.Level1)
{
    std::vector<std::shared_ptr<Reader>> readerList;
    std::shared_ptr<SEService> seService = std::make_shared<SEService>();
    seService->GetReaders(readerList);
    EXPECT_TRUE(seService != nullptr);
}
} // TEST
} // SE
} // OHOS